﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SocketServer
{
    public partial class Form1 : Form
    {
        private Socket socketwatch = null;
        private Thread threadwatch = null;
        private string linebreak = "\r\n";
        private Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
        private Dictionary<string, string> dictime = new Dictionary<string, string>();
        public Form1()
        {
            InitializeComponent();
            InitData();
            ShowConnected();

        }
        private void InitData()
        {
            GetNativeIp();
            text_port.Text = "8080";
        }
   
        //获取本机ip
        public void GetNativeIp()
         {    
               IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
               foreach(var ip in hostEntry.AddressList)
              {
                  if (ip.AddressFamily == AddressFamily.InterNetwork)
                  {
                      text_ipaddress.Text = ip.ToString();
                  }
             }
         }

        private void btn_start_Click(object sender, EventArgs e)
        {
            //创立一个监听客户端消息的对象
            socketwatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定用户输入的ip和地址
            socketwatch.Bind(new IPEndPoint(IPAddress.Parse(text_ipaddress.Text.Trim()), int.Parse(text_port.Text.Trim())));
            socketwatch.Listen(30);//指定等待连接队列的最大长度
            //创建一个监听线程
            threadwatch = new Thread(Listen);
            threadwatch.IsBackground = true;
            threadwatch.Start();
            text_records.AppendText("开始监听客户端消息---" + DateTime.Now.ToString() + linebreak);
            btn_start.Enabled = false;
            btn_start.BackColor = Color.Green;
        }
        private void Listen()
        {
            while (true)
            {
                if (socketwatch == null) return;
                Socket socketConnection    = socketwatch.Accept();//接受客户端请求，并返回一个和客户端进行通讯的socket对象
                if (socketConnection != null)
                {
                    //socketConnection.RemoteEndPoint.ToString() 获取客户端的IP和端口号
                    dic.Add(socketConnection.RemoteEndPoint.ToString(), socketConnection);//将socket 对象存入字典
                    dictime.Add(socketConnection.RemoteEndPoint.ToString(), DateTime.Now.ToString());//存入连接时间
                    text_records.Invoke(new Action(() => text_records.AppendText($"{socketConnection.RemoteEndPoint}---已连接---" + DateTime.Now.ToString() + linebreak)));
                    Task.Run(new Action(() =>
                    {
                        while (true)
                        {
                            try
                            {
                                if (socketConnection == null) return;
                                byte[] buffer = new byte[1024 * 1024 * 2];
                                int length = socketConnection.Receive(buffer);//将收到的数据存入缓存区并返回收到的字节数
                                string  serverRecive = Encoding.UTF8.GetString(buffer).Replace("\0", "");
                                string reciveString = socketConnection.RemoteEndPoint.ToString()+":"+linebreak+Encoding.UTF8.GetString(buffer).Replace("\0", "");
                                transsend(reciveString, socketConnection);//转发客户端的消息到其它客户端
                                text_records.Invoke(new Action(() => { text_records.AppendText(DateTime.Now.ToString() + linebreak + socketConnection.RemoteEndPoint.ToString() + $":{serverRecive}" + linebreak); }));
                            }
                            catch (Exception e)
                            {
                                text_records.Invoke(new Action(() => {
                                    text_records.AppendText(DateTime.Now.ToString() + linebreak + socketConnection.RemoteEndPoint.ToString() + $"{e.Message}" + linebreak);
                                }));
                                dic.Remove(socketConnection.RemoteEndPoint.ToString());//断开连接移除字典
                                dictime.Remove(socketConnection.RemoteEndPoint.ToString());
                                return;
                            }

                        }
                    }));
                }
               
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message"></param>
        private void send(string message)
        {       
            byte[] data = Encoding.UTF8.GetBytes("服务器:" + linebreak + message);
            foreach (var item in dic)
            {      
                 item.Value.Send(data);
            }
            // socketConnection.Send(data);
        }
        /// <summary>
        /// 转发消息
        /// </summary>
        /// <param name="message"></param>
        /// <param name="connection"></param>
        private void transsend(string message,Socket connection)
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            foreach(var item in dic)
            {
                if (item.Key !=connection.RemoteEndPoint.ToString())
                {
                    item.Value.Send(data);
                }
            }
        }

        private void btn_send_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(text_send.Text))
            {
                send(text_send.Text.Trim());
                text_records.AppendText( DateTime.Now.ToString() + linebreak+ "服务器" + $":{text_send.Text.Trim()}" +linebreak);
                text_send.Text = string.Empty;
            }
            else MessageBox.Show("请输入内容", "提示", MessageBoxButtons.OK);
        }

        private void ShowConnected()
        {
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Interval=3000;
            timer.Elapsed += Timer_Elapsed;
            timer.Start();
        }

        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //将连接用户信息显示出来
            listView1.Invoke(new Action(() =>
            {
                listView1.Items.Clear();
                foreach (var item in dictime)
                {   
                    ListViewItem item1 = new ListViewItem(item.Key);
                    item1.SubItems.Add(item.Value);
                    listView1.Items.Add(item1);
                }
                label_count.Text = listView1.Items.Count.ToString();
            }));
            //将连接用户信息发送到每一个客户端
            string message = "type=1"+JsonConvert.SerializeObject(dictime);
            foreach(var item in dic)
            {
                    byte[] data = Encoding.UTF8.GetBytes(message);
                    item.Value.Send(data);
            }
           

        }
    }
} 
